
import { addElClass, on } from './util';

/**
 * 轮播
 * @param pageContainerEl 存放轮播页面的容器(页面html已经构造好) 
 * @param pageItemClassName 页面的类名
 * @param pageEnterClass 页面进场时要加什么类名(退场时会移除),放空不处理
 * @param pageExitClass 页面退场时要加什么类名(进场时会移除),放空不处理
 * @param ctlContainerEl 存放控制点的容器,需要自行构造控制器
 * @param createCarouselCtlHandler 控制点的构造实例处理器
 * @param pagePlayTime 一页播放多少毫秒换下一页(记得算好进场和退场动画)
 * @param pageDelayNextTime 播放完延迟多少毫秒开始下一张(为了退场动画完成)
*/
function Carousel(pageContainerEl, pageItemClassName, pageEnterClass, pageExitClass, ctlContainerEl, createCarouselCtlHandler,
    pagePlayTime, pageDelayNextTime, debugNoRun) {
    this.pages = [];
    this.ctls = [];
    this.pageEnterClass = pageEnterClass;
    this.pageExitClass = pageExitClass;
    this.playIndex = -1;
    this.playTimer = null;//播放中的定时器
    this.playPrevTick = 0;
    this.playDurationTime = 0;
    this.pagePlayTime = pagePlayTime;
    this.pageDelayNextTime = pageDelayNextTime;
    this.playNextTimer = null;//下一页的定时器

    let pageEls = pageContainerEl.getElementsByClassName(pageItemClassName);
    if (!pageEls || pageEls.length <= 0) throw new Error('pageContainerEl is empty');
    var index = -1;
    for (var pageEl of pageEls) {
        index++;
        var page = {
            pageEl: pageEl,
            index: index,
        };
        this.pages.push(page);
        addElClass(pageEl, this.pageEnterClass, this.pageExitClass);
        //初始化控制点
        var ctl = createCarouselCtlHandler();
        ctlContainerEl.appendChild(ctl.el);
        if (ctl.supportEnabled) {
            ctl.setEnabled(false);
        }
        this.ctls.push(ctl);

        //注册点击播放
        on(ctl.el, ['click', 'touchstart'], function (page) {
            this.play(page.index);
        }, this, page);

    }

    //调试用的,直接不播放并且不注册,手动控制调试用
    if (debugNoRun) return;

    //初始化完直接开始播放
    this.playNext();

    pageContainerEl.addEventListener('mouseover', (function () {
        this.pauseCurrent();
    }).bind(this));
    pageContainerEl.addEventListener('mouseout', (function () {
        this.playCurrent();
    }).bind(this));
}
Carousel.prototype.playCurrent = function () {
    if (this.playTimer) {
        clearInterval(this.playTimer);
    }
    this.playPrevTick = Date.now();
    this.playTimer = setInterval((function () {
        var now = Date.now();
        var dt = now - this.playPrevTick;
        this.playPrevTick = now;
        this.playDurationTime += dt;
        var ctl = this.ctls[this.playIndex];
        if (ctl.supportLoading()) {
            //支持loading效果则设置百分比
            ctl.setPercent(this.playDurationTime / this.pagePlayTime);
        }
        if (this.playDurationTime >= this.pagePlayTime) {
            //播放满了,开始切换下一个
            this.exitCurrent((function () {
                this.playNext();
            }).bind(this));
        }
    }).bind(this), 20);
};
Carousel.prototype.exitCurrent = function (cb) {
    var page = this.pages[this.playIndex];
    var ctl = this.ctls[this.playIndex];

    //加上退场动画(完成退成后再移除进场动画)
    addElClass(page.pageEl, null, this.pageExitClass);
    if (ctl.supportEnabled()) {
        ctl.setEnabled(false);
    }
    //清理播放定时器
    if (this.playTimer) {
        clearInterval(this.playTimer);
        this.playTimer = null;
    }
    if (this.playNextTimer) clearTimeout(this.playNextTimer);
    this.playNextTimer = setTimeout((function () {
        //退场完毕,清理进场动画
        addElClass(page.pageEl, this.pageEnterClass, null);
        cb && cb();
    }).bind(this), this.pageDelayNextTime);
};
Carousel.prototype.playNext = function () {
    this.playIndex++;
    if (this.playIndex >= this.pages.length) this.playIndex = 0;
    this.play(this.playIndex);
};
Carousel.prototype.play = function (index) {
    //具体的启动播放方法
    var run = (function () {
        this.playIndex = index;
        if (this.playTimer) {
            clearInterval(this.playTimer);
            this.playTimer = null;
        }
        if (this.playNextTimer) {
            clearTimeout(this.playNextTimer);
            this.playNextTimer = null;
        }

        var ctl = this.ctls[this.playIndex];
        var page = this.pages[this.playIndex];
        if (ctl.supportEnabled()) {
            ctl.setEnabled(true);
        }
        //移除退场动画,加上进场动画
        addElClass(page.pageEl, this.pageExitClass, this.pageEnterClass);
        //开始播放当前页
        this.playDurationTime = 0;
        this.playCurrent();
    }).bind(this);

    if (this.playIndex !== index) {
        //如果有发生切换,则退出当前的再开始新的
        this.exitCurrent(run);
    } else {
        //没切换直接播放(可以通过提前设置好playIndex来达成跳过自动流程)
        run();
    }
};
/**暂停当前页的播放(调用playCurrent继续播放未完的)*/
Carousel.prototype.pauseCurrent = function () {
    if (this.playTimer) {
        clearInterval(this.playTimer);
        this.playTimer = null;
    }
};


/**
 * 轮播的控制点(设计成适配器,多种控制点的实现都可以传入)
 * @param ins 实例
*/
function CarouselCtl(ins) {
    this.ins = ins;
    this.el = this.ins.initEl();
}
CarouselCtl.prototype.supportLoading = function () {
    return !!this.ins.setPercent
};
CarouselCtl.prototype.supportEnabled = function () {
    return !!this.ins.setEnabled
};
CarouselCtl.prototype.setEnabled = function (enabled) {
    return this.ins.setEnabled(enabled);
};
CarouselCtl.prototype.setPercent = function (percent) {
    return this.ins.setPercent(percent);
};


export {
    Carousel,
    CarouselCtl,
}